package sc.prototype.pfs.eventnotify.executor.impl;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sc.prototype.pfs.eventnotify.Configs;
import sc.prototype.pfs.eventnotify.executor.NotifyExecutor;
import sc.prototype.pfs.eventnotify.model.Notice;
import sc.prototype.pfs.eventnotify.model.NoticeContent;
import sc.prototype.pfs.eventnotify.model.NotifyContext;
import sc.prototype.pfs.eventnotify.model.NotifyResult;
import sc.prototype.pfs.eventnotify.model.ParamKey;
import sc.prototype.pfs.eventnotify.util.ExtensionHelper;

import com.alibaba.fastjson.JSON;

public class HttpNotifyExecutor extends NotifyExecutor {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    HttpClient httpClient;

    @Override
    public NotifyResult processSendNotice(Notice notice, NotifyContext context) throws URISyntaxException,
            ClientProtocolException, IOException {
        HTTPExtensionHelper helper = new HTTPExtensionHelper(notice);
        NoticeContent content = notice.getContent();
        String noticeValue = JSON.toJSONString(content.getContent());
        BasicNameValuePair nvp = new BasicNameValuePair("notice", noticeValue);
        UrlEncodedFormEntity reqEntity = new UrlEncodedFormEntity(Arrays.asList(nvp), Configs.INS.DEFAULT_ENCODING);
        HttpPost request = new HttpPost(notice.getNotifyTarget().getNotifyAddress());
        request.setEntity(reqEntity);
        HttpResponse response = httpClient.execute(request);
        HttpEntity respEntity = response.getEntity();
        if (respEntity == null) {
            return NotifyResult.fail("[PFS]null response entity");
        }
        String respEncoding = helper.getResponseEncoding();
        String resp = EntityUtils.toString(respEntity, respEncoding);
        return parseResult(resp);
    }

    public NotifyResult parseResult(String response) {
        if (response == null) {
            return NotifyResult.fail("[PPS]null response");
        }
        response = response.trim();
        if (Configs.INS.HTTP_RESPONSE_OK.equals(response)
                || response.startsWith(Configs.INS.HTTP_RESPONSE_OK_STARTSWITH)) {
            return NotifyResult.success(response);
        } else {
            return NotifyResult.fail(response);
        }
    }

    public static class HTTPExtensionHelper extends ExtensionHelper {

        public HTTPExtensionHelper(Notice notice) {
            super(notice);
        }

        public String getResponseEncoding() {
            return get(RESPONSE_ENCODING, Configs.INS.HTTP_RESPONSE_ENCODING, true);
        }

    }

    public static final ParamKey RESPONSE_ENCODING;

    public static final List<ParamKey> PARAM_KEYS;
    static {
        RESPONSE_ENCODING = new ParamKey("RESPONSE_ENCODING", "Http响应编码", ".*", false);
        PARAM_KEYS = Arrays.asList(RESPONSE_ENCODING);
    }

    @Override
    public List<ParamKey> getExtParamKeys() {
        return PARAM_KEYS;
    }

    public HttpClient getHttpClient() {
        return httpClient;
    }

    public void setHttpClient(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

}
